// [参考](https://docs.mapbox.com/mapbox-gl-js/example/drag-a-point/)
import * as turf from "@turf/turf";
import EditBase from "./EditBase";
import { toCentroidGeojson, toPointGeojson } from "./utils";

export default class EditRotate extends EditBase {
	constructor(map) {
		super(map);

		this.editLayerId = "edit-rotate-layer";

		this.initEditLayers();
	}

	initEditLayers() {
		const { map, editLayerId } = this;

		const editRotateLayer = {
			id: editLayerId,
			type: "symbol",
			source: {
				type: "geojson",
				data: {
					type: "FeatureCollection",
					features: [],
				},
			},
			layout: {
				"icon-image": ["get", "icon"],
				"icon-size": 1,
				// "icon-offset": [0, -20],
			},
			paint: {
				"icon-opacity": 1,
				"icon-halo-color": "red",
				"icon-halo-width": 10,
			},
		};

		map.addLayer(editRotateLayer);

		this.editSource = map.getSource(editLayerId);
	}

	onMouseEnter() {
		const { canvas } = this;
		canvas.style.cursor = "move";
	}

	onMouseLeave() {
		const { canvas } = this;
		canvas.style.cursor = "";
	}

	onMove(callback, e) {
		const { canvas, points, editSource } = this;

		canvas.style.cursor = "grabbing";

		const coords = e.lngLat;
		const end = turf.point([coords.lng, coords.lat]);
		const centroid = toCentroidGeojson(points);
		const bearing1 = turf.bearing(centroid, end, { final: true });
		const bearing2 = turf.bearing(centroid, turf.point(points[0]), {
			final: true,
		});
		const angle = bearing1 - bearing2;

		const features = toPointGeojson(points);
		const rotates = turf.transformRotate(features, angle, { mutate: true });

		const newPoints = rotates.features.map(
			(feature) => feature.geometry.coordinates,
		);

		const rotatePnt = turf.point(newPoints[0], { icon: "rotate-icon" });

		editSource.setData(rotatePnt);

		callback(newPoints);
	}

	updateEditSource(points) {
		let data = null;
		if (points.length) {
			data = turf.point(points[0], { icon: "rotate-icon" });
		} else {
			data = toPointGeojson(points);
		}

		this.editSource.setData(data);

		this.points = points;
	}
}
